package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.MoveTeachPlanDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Mr.M
 * @version 1.0
 * @description 课程基本信息管理业务接口实现类
 * @date 2023/2/14 15:06
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {

    /**
     * 课程计划第一级别
     */
    private static final int GRADE_ONE = 1;


    /**
     * 课程计划第一级别
     */
    private static final int GRADE_SECOND = 2;

    /**
     * 上移
     */
    private static final String MOVE_UP = "moveup";


    /**
     * 下移
     */
    private static final String MOVE_DOWN = "movedown";


    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    @Override
    public List<TeachplanDto> findTeachplanTree(Long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {
        Long id = saveTeachplanDto.getId();
        if (id != null) {
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(saveTeachplanDto, teachplan);
            teachplanMapper.updateById(teachplan);
        } else {
            int count = getTeachplanCount(saveTeachplanDto.getCourseId(), saveTeachplanDto.getParentid());
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            //设置排序号
            teachplan.setOrderby(count + 1);
            teachplanMapper.insert(teachplan);
        }
    }

    @Transactional
    @Override
    public void deleteTeachplan(Long id) {
        Teachplan teachplan = teachplanMapper.selectById(id);
        //确认第一级别下大章节下没有小章节才可以删除
        if (GRADE_ONE == teachplan.getGrade()) {
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getParentid, id);
            Integer count = teachplanMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("该章节下有小章节，无法删除");
            } else {
                teachplanMapper.deleteById(id);
            }
        }
        //删除第二级别的小章节同时要将teachplan_media表关联信息删除
        if (GRADE_SECOND == teachplan.getGrade()) {
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getId, id);
            Integer count = teachplanMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("该章节下有小章节，无法删除");
            } else {
                //删除teachplan_media关联信息
                LambdaQueryWrapper<TeachplanMedia> deleteQueryWrapper = new LambdaQueryWrapper<>();
                deleteQueryWrapper.eq(TeachplanMedia::getTeachplanId, teachplan.getId());
                Integer mediaCount = teachplanMediaMapper.selectCount(deleteQueryWrapper);
                if (mediaCount > 0) {
                    int deleteCount = teachplanMediaMapper.delete(deleteQueryWrapper);
                    //删除课程计划信息(确保课程信息删除之后)
                    if (deleteCount > 0) {
                        teachplanMapper.deleteById(id);
                    }
                }
            }
        }
    }

    @Override
    public void moveTeachplan(String moveType, Long id, MoveTeachPlanDto moveTeachPlanDto) {
        //1.查询当前位置课程计划信息
        LambdaQueryWrapper<Teachplan> currentQueryWrapper = new LambdaQueryWrapper<>();
        currentQueryWrapper.eq(Teachplan::getId, id);
        currentQueryWrapper.eq(Teachplan::getOrderby, moveTeachPlanDto.getCurrentOrderBy());
        Teachplan teachplan = teachplanMapper.selectOne(currentQueryWrapper);
        if (teachplan == null) {
            throw new RuntimeException("当前课程计划不存在");
        }
        //2..查询目标位置课程计划信息
        LambdaQueryWrapper<Teachplan> nextQueryWrapper = new LambdaQueryWrapper<>();
        nextQueryWrapper.eq(Teachplan::getParentid, teachplan.getParentid());
        nextQueryWrapper.eq(Teachplan::getOrderby, moveTeachPlanDto.getNextOrderBy());
        Teachplan nextTeachPlan = teachplanMapper.selectOne(nextQueryWrapper);
        if (nextTeachPlan == null) {
            throw new RuntimeException("目标课程计划不存在");
        }
        //对上移（当前为第一个课程计划）或下移（当前为最后一个课程计划）不做处理
        int count = getTeachplanCount(teachplan.getCourseId(), teachplan.getParentid());
        if (MOVE_UP.equals(moveType) && moveTeachPlanDto.getCurrentOrderBy() == 1) {
            throw new RuntimeException("已经是第一个课程计划，无法上移");
        } else if (MOVE_DOWN.equals(moveType) && moveTeachPlanDto.getCurrentOrderBy() == count) {
            throw new RuntimeException("已经是最后一个课程计划，无法下移");
        }
        //设置移动到目标位置，课程计划的排序
        teachplan.setOrderby(moveTeachPlanDto.getNextOrderBy());
        teachplanMapper.updateById(teachplan);
        //设置移动到当前位置，课程计划的排序
        nextTeachPlan.setOrderby(moveTeachPlanDto.getCurrentOrderBy());
        teachplanMapper.updateById(nextTeachPlan);
    }

    @Transactional
    @Override
    public void associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //1.查询课程计划
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        //2.对课程计划进行判空
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if (teachplan == null) {
            XueChengPlusException.cast("课程计划不存在");
        }
        //3.先删除原有的课程计划
        int delete = teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId, bindTeachplanMediaDto.getTeachplanId()));
        //4.添加新纪录
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        //5.设置课程计划与媒资关系绑定关系信息
        BeanUtils.copyProperties(bindTeachplanMediaDto, teachplanMedia);
        //5.1 设置课程计划标识
        teachplanMedia.setTeachplanId(teachplanId);
        //5.2 设置媒资id
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        //5.3设置课程标识
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMediaMapper.insert(teachplanMedia);
    }

    private int getTeachplanCount(Long courseId, Long parentId) {
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId, courseId);
        queryWrapper.eq(Teachplan::getParentid, parentId);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return count;
    }
}
